home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
vutex
/
vaxvms.chg
< prev
next >
Wrap
Text File
|
1990-10-01
|
19KB
|
633 lines
VMS changes file for the ASCII driver written by Warren Wolfe, Aug, 1988
Copyright 1987 CUBE Software, Victoria, B.C., Canada
@x [2]
@d banner=='This is ',clone,', Version 1.00'
@y
@d banner=='This is ',clone,', VAX/VMS Version 1.00'
@z
@x
@d othercases == others: {default for cases not listed explicitly}
@d endcases == @+end {follows the default case in an extended |case| statement}
@f othercases == else
@f endcases == end
@y
@d othercases == otherwise {default for cases not listed explicitly}
@d endcases == @+end {follows the default case in an extended |case| statement}
@f othercases == else
@f endcases == end
@z
@x [4] add tfm_file,gen_input,and input to program header
@p program vutex(dvi_file,bit_file,input,output);
@y
@p
@\@=[inherit('sys$library:starlet')]@>@\
{allows us to use system symbols and routines}
program vutex(dvi_file,bit_file,tfm_file,gen_input,input,output);
@z
@x
procedure initialize; {this procedure gets things started properly}
var i:integer; {loop index for initializations}
begin print_ln(banner);@/
@y
@<Procedures for initialization@>@/
procedure initialize; {this procedure gets things started properly}
var i:integer; {loop index for initializations}
begin
@<Preset initial values@>@/
print_ln(banner);@/
@z
@x
Some \PASCAL\ compilers use the original name |char| for the data type
associated with the characters in text files, while other \PASCAL s
consider |char| to be a 64-element subrange of a larger data type that has
some other name. In order to accommodate this difference, we shall use
the name |text_char| to stand for the data type of the characters in the
output file. We shall also assume that |text_char| consists of
the elements |chr(first_text_char)| through |chr(last_text_char)|,
inclusive. The following definitions should be adjusted if necessary.
@^system dependencies@>
@d text_char == char {the data type of characters in text files}
@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
@d last_text_char=127 {ordinal number of the largest element of |text_char|}
@<Types...@>=
@!text_file=packed file of text_char;
@y
Some \PASCAL\ compilers use the original name |char| for the data type
associated with the characters in text files, while other \PASCAL s
consider |char| to be a 64-element subrange of a larger data type that has
some other name. In order to accommodate this difference, we shall use
the name |text_char| to stand for the data type of the characters in the
output file. We shall also assume that |text_char| consists of
the elements |chr(first_text_char)| through |chr(last_text_char)|,
inclusive. The following definitions should be adjusted if necessary.
@^system dependencies@>
@d text_char == char {the data type of characters in text files}
@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
@d last_text_char=127 {ordinal number of the largest element of |text_char|}
@<Types...@>=
@!text_file=text;
@z
@x
@!byte_file=packed file of eight_bits; {files that contain binary data}
@y
{later we'll define files that contain binary data}
@z
@x
@!dvi_file:byte_file; {the stuff we are \.{DVI}typing}
@!tfm_file:byte_file; {a font metric file}
@y
@!dvi_file:packed file of byte_block; {the stuff we are \.{DVI}typing}
@!tfm_file:packed file of byte_block; {a font metric file}
@!dvi_count:integer; {number of bytes read from current block of |dvi_file|}
@!tfm_count:integer; {number of bytes read from current block of |tfm_file|}
@!dvi_blocks:integer; {number of blocks in |dvi_file|}
@z
@x Initialize byte counter for block in open_dvi_file
begin reset(dvi_file);
@y
begin reset(dvi_file);
dvi_count:=0;
@z
@x And again in reopen_dvi_file
begin reset(dvi_file);
@y
begin reset(dvi_file);
dvi_count:=0;
@z
@x
begin reset(tfm_file,cur_name);
@y
begin close(tfm_file,@=error@>:=@=continue@>); {stupid Vax/VMS run-times}
open(tfm_file,cur_name,@=old@>,@=error@>:=@=continue@>);
reset(tfm_file,@=error@>:=@=continue@>);
tfm_count:=0;
@z
@x
begin reset(gen_input, cur_name) ;
@y
begin close(gen_input,@=error@>:=@=continue@>);
open(gen_input,cur_name,@=old@>,@=error@>:=@=message@>);
reset(gen_input,@=error@>:=@=message@>);
@z
@x
@p function get_byte:integer; {returns the next byte, unsigned}
var b:eight_bits;
begin if eof(dvi_file) then get_byte:=0
else begin read(dvi_file,b); incr(cur_loc); get_byte:=b;
end;
end;
@#
function signed_byte:integer; {returns the next byte, signed}
var b:eight_bits;
begin read(dvi_file,b); incr(cur_loc);
if b<128 then signed_byte:=b @+ else signed_byte:=b-256;
end;
@#
function get_two_bytes:integer; {returns the next two bytes, unsigned}
var a,@!b:eight_bits;
begin read(dvi_file,a); read(dvi_file,b);
cur_loc:=cur_loc+2;
get_two_bytes:=a*256+b;
end;
@#
function signed_pair:integer; {returns the next two bytes, signed}
var a,@!b:eight_bits;
begin read(dvi_file,a); read(dvi_file,b);
cur_loc:=cur_loc+2;
if a<128 then signed_pair:=a*256+b
else signed_pair:=(a-256)*256+b;
end;
@#
function get_three_bytes:integer; {returns the next three bytes, unsigned}
var a,@!b,@!c:eight_bits;
begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c);
cur_loc:=cur_loc+3;
get_three_bytes:=(a*256+b)*256+c;
end;
@#
function signed_trio:integer; {returns the next three bytes, signed}
var a,@!b,@!c:eight_bits;
begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c);
cur_loc:=cur_loc+3;
if a<128 then signed_trio:=(a*256+b)*256+c
else signed_trio:=((a-256)*256+b)*256+c;
end;
@#
function signed_quad:integer; {returns the next four bytes, signed}
var a,@!b,@!c,@!d:eight_bits;
begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d);
cur_loc:=cur_loc+4;
if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
end;
@y
@d read_dvi_file(#)==begin
if dvi_count=block_size then begin
get(dvi_file,@=error:=continue@>); dvi_count:=0;
end;
#:=dvi_file^[dvi_count];
incr(dvi_count);
end
@p function get_byte:integer; {returns the next byte, unsigned}
var b:eight_bits;
begin if eof(dvi_file) then get_byte:=0
else begin read_dvi_file(b); incr(cur_loc); get_byte:=b;
end;
end;
@#
function signed_byte:integer; {returns the next byte, signed}
var b:eight_bits;
begin read_dvi_file(b); incr(cur_loc);
if b<128 then signed_byte:=b @+ else signed_byte:=b-256;
end;
@#
function get_two_bytes:integer; {returns the next two bytes, unsigned}
var a,@!b:eight_bits;
begin read_dvi_file(a); read_dvi_file(b);
cur_loc:=cur_loc+2;
get_two_bytes:=a*256+b;
end;
@#
function signed_pair:integer; {returns the next two bytes, signed}
var a,@!b:eight_bits;
begin read_dvi_file(a); read_dvi_file(b);
cur_loc:=cur_loc+2;
if a<128 then signed_pair:=a*256+b
else signed_pair:=(a-256)*256+b;
end;
@#
function get_three_bytes:integer; {returns the next three bytes, unsigned}
var a,@!b,@!c:eight_bits;
begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c);
cur_loc:=cur_loc+3;
get_three_bytes:=(a*256+b)*256+c;
end;
@#
function signed_trio:integer; {returns the next three bytes, signed}
var a,@!b,@!c:eight_bits;
begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c);
cur_loc:=cur_loc+3;
if a<128 then signed_trio:=(a*256+b)*256+c
else signed_trio:=((a-256)*256+b)*256+c;
end;
@#
function signed_quad:integer; {returns the next four bytes, signed}
var a,@!b,@!c,@!d:eight_bits;
begin read_dvi_file(a); read_dvi_file(b); read_dvi_file(c); read_dvi_file(d);
cur_loc:=cur_loc+4;
if a<128 then signed_quad:=((a*256+b)*256+c)*256+d
else signed_quad:=(((a-256)*256+b)*256+c)*256+d;
end;
@z
@x [37]
@ We need a function that will read in a word from the \.{TFM} file. If
the particular system
@^system dependencies@>
requires buffering, here is the place to do it. It also sets a global flag
|eof_tfm| when it reaches the end of the file. If this flag is set on
entrance to |load_tfm_file|, it is assumed that the file is bad.
@p function tfm_integer : integer ;
var i:integer;
begin read(tfm_file, i);
eof_tfm:=eof(tfm_file);
tfm_integer:=i;
end;
@ There is nothing wrong with defining |eof_tfm| here.
@<Glob...@>=
@!eof_tfm:boolean; {true when end of \.{TFM} file is reached.}
@y
@ We need a function that will read in a word from the \.{TFM} file. If
the particular system
@^system dependencies@>
requires buffering, here is the place to do it. It also sets a global flag
|eof_tfm| when it reaches the end of the file. If this flag is set on
entrance to |load_tfm_file|, it is assumed that the file is bad.
Since |tfm_file| is blocked, we need a function to read an integer
from it.
@d read_tfm_file(#)==begin
if tfm_count=block_size then begin
get(tfm_file); tfm_count:=0;
end;
#:=tfm_file^[tfm_count];
incr(tfm_count);
end
@#
@p function tfm_integer : integer;
var i,@!result,@!temp:integer;
begin
result := 0;
for i:=1 to 4 do begin@/
read_tfm_file(temp); result := result*two_8+temp;
end;
eof_tfm := eof(tfm_file);
tfm_integer := result ;
end;
@ There is nothing wrong with defining |eof_tfm| here.
@<Glob...@>=
@!eof_tfm:boolean; {true when end of \.{TFM} file is reached.}
@z
@x
and |term_out| for terminal output.
@^system dependencies@>
@<Glob...@>=
@!buffer:array[0..terminal_line_length] of ASCII_code;
@!term_in:text_file; {the terminal, considered as an input file}
@!term_out:text_file; {the terminal, considered as an output file}
@y
and |term_out| for terminal output.
@^system dependencies@>
@d term_in==input {the terminal, considered as an input file}
@d term_out==output {the terminal, considered as an output file}
@<Glob...@>=
@!buffer:array[0..terminal_line_length] of ASCII_code;
@!buf_length:integer;
@z
@x
@ Since the terminal is being used for both input and output, some systems
need a special routine to make sure that the user can see a prompt message
before waiting for input based on that message. (Otherwise the message
may just be sitting in a hidden buffer somewhere, and the user will have
no idea what the program is waiting for.) We shall call a system-dependent
subroutine |update_terminal| in order to avoid this problem.
@^system dependencies@>
@d update_terminal == break(term_out) {empty the terminal output buffer}
@ During the dialog, \vutex\ will treat the first blank space in a
line as the end of that line. Therefore |input_ln| makes sure that there
is always at least one blank space in |buffer|.
@^system dependencies@>
@p procedure input_ln; {inputs a line from the terminal}
var k:0..terminal_line_length;
begin update_terminal; reset(term_in);
if eoln(term_in) then read_ln(term_in);
k:=0;
while (k<terminal_line_length)and not eoln(term_in) do
begin buffer[k]:=xord[term_in^]; incr(k); get(term_in);
end;
buffer[k]:=" ";
end;
@y
@ Since the terminal is being used for both input and output, some systems
need a special routine to make sure that the user can see a prompt message
before waiting for input based on that message. (Otherwise the message
may just be sitting in a hidden buffer somewhere, and the user will have
no idea what the program is waiting for.) We shall call a system-dependent
subroutine |update_terminal| in order to avoid this problem.
@^system dependencies@>
@d update_terminal == do_nothing {empty the terminal output buffer}
@ During the dialog, \vutex\ will treat the first blank space in a
line as the end of that line. Therefore |input_ln| makes sure that there
is always at least one blank space in |buffer|.
@^system dependencies@>
@p procedure input_ln; {inputs a line from the terminal}
var k:0..terminal_line_length;
begin update_terminal; reset(term_in) ;
k:=0;
if eoln(term_in) then write_ln
else begin
while (k<terminal_line_length)and not eoln(term_in) do begin
buffer[k]:=xord[term_in^];
incr(k); get(term_in);
end;
end;
buffer[k]:=" ";
end;
@z
@x [52]
@p procedure dialog;
var k:integer; {loop variable}
begin rewrite(term_out); {prepare the terminal for output}
@<Determine the desired |start_count| values@>;
@<Determine the desired |max_pages|@>;
@<Determine the truncation |print_width|@>;
@<Determine the compression mode@>;
@<Print all the selected options@>;
if compress and (print_width > (page_width * 3 div 4)) then
page_width := 4 * print_width div 3
else if (not compress) and (print_width > page_width - hh_offset) then
page_width := print_width + hh_offset;
if page_width > max_p_width then
begin
page_width := max_p_width;
print_width := page_width - hh_offset;
end;
num_lines := total_rast div page_width;
end;
@y
@d batch == 0 { batch mode response}
@d online == 1 { online mode response}
@p procedure dialog;
var i, k:integer; {loop variable}
interaction: integer; { to contain response from mode query}
begin rewrite(term_out); {prepare the terminal for output}
if buf_length<=0 then begin
@<Determine the desired |start_count| values@>;
@<Determine the desired |max_pages|@>;
@<Determine the truncation |print_width|@>;
@<Determine the compression mode@>;
@<Print all the selected options@>;
end else @<Determine the options from the command buffer@>;
if compress and (print_width > (page_width * 3 div 4)) then
page_width := 4 * print_width div 3
else if (not compress) and (print_width > page_width - hh_offset) then
page_width := print_width + hh_offset;
if page_width > max_p_width then
begin
page_width := max_p_width;
print_width := page_width - hh_offset;
end;
num_lines := total_rast div page_width;
end;
@ Here are two new sections to support getting the options from the
command line.
@<Determine the options...@>==
begin
buffer[buf_length+1] := "?" ; { end it with a question mark }
buf_ptr := 0 ;
repeat
case buffer[buf_ptr] of
" ",",","G","g" : ;
"S","s" : begin
@<Skip to parameter@> ; k := 0 ;
@<Parse the desired |start_vals|@> ;
end ;
"P","p" : begin
@<Skip to parameter@> ;
@<Parse the desired |max_pages|@> ;
end ;
"W","w" : begin
@<Skip to parameter@> ;
@<Parse the desired |print_width|@> ;
end ;
"T","t" : compress := false ;
"D","d" : out_mode := 1 ;
othercases
print_ln('Error on command line. Skipping: ',xchr[buffer[buf_ptr]]);
@.Error on command line...:@>
endcases ;
incr(buf_ptr);
until buf_ptr >= buf_length;
@<Print all the selected options@>;
end
@ @<Skip to parameter@>==
while (buf_ptr < buf_length) and (buffer[buf_ptr] <> " ") and
(buffer[buf_ptr] <> "=") and (buffer[buf_ptr] <> ",") do
incr(buf_ptr);
if buffer[buf_ptr] = "=" then incr(buf_ptr);
@z
@x [68] set up directory names
@d tfm_directory_name=='TeXfonts:'
@d tfm_directory_name_length=9
@y
@d tfm_directory_name=='staff:[wolfe]'
@d tfm_directory_name_length=13
@z
@x [122]
@d font_list_file=='nonASCII.tex.fnt' {change this to correct name}
@d list_len==16
@y
@d font_list_file=='nonASCIItex.dat'
@d list_len==23
@z
@x [207]
This section should be replaced, if necessary, by changes to the program
that are necessary to make \vutex\ work at a particular installation.
Any additional routines should be inserted here.
@^system dependencies@>
@y
Here are the remaining changes to the program
that are necessary to make \.{DVItype} work on Vax/VMS.
@<Const...@>==
@!block_size=512;
@!two_8= @'400;
@ @<Types...@>==
@!byte_block=packed array [0..block_size-1] of 0..255;
@ On Vax/VMS we need the following special definitions, types, variables
and procedures to be able to get the file name from the command line,
or to prompt for them.
@d VAX_direct==@=direct@>
@d VAX_fixed==@=fixed@>
@d VAX_volatile==@=volatile@>
@d VAX_immed==@=%immed @>
@d VAX_external==@=external@>
@d VAX_stdescr==@=%stdescr @>
@d VAX_lib_get_foreign==@= lib$get_foreign@>
@d VAX_length==@=length @>
@d VAX_fab_type==@= FAB$TYPE @>
@d VAX_rab_type==@= RAB$TYPE @>
@d VAX_xab_type==@= XAB$TYPE @>
@d VAX_fab_xab==@= FAB$L_XAB @>
@d VAX_xab_nxt==@= XAB$L_NXT @>
@d VAX_xab_cod==@= XAB$B_COD @>
@d VAX_xab_fhc==@= XAB$C_FHC @>
@d VAX_xab_ebk==@= XAB$L_EBK @>
@ @<Types...@>=
@!sixteen_bits= 0..65535;
@ @<Glob...@>==
@!type_file: text;
@!com_line:packed array[1..300] of char;
@!cmd_len:sixteen_bits;
@!cmd_i,cmd_e,cmd_o:integer;
@!dvi_fname,@!bit_fname:varying [300] of char;
@!got_file_name: boolean;
@ @<Preset init...@>=
open(output,'SYS$OUTPUT',@=error:=continue@>); {FIX ME! JUNK FOR RUN-TIME BUG}
cmd_i:=0;
VAX_lib_get_foreign(com_line,,cmd_len,cmd_i);
cmd_i:=1;
while (cmd_i<=cmd_len) and (com_line[cmd_i]=' ') do incr(cmd_i);
cmd_o:=cmd_i;
while (cmd_o<cmd_len) and (com_line[cmd_o]<>'\') do incr(cmd_o);
if cmd_o<cmd_len then begin
for i:=1 to cmd_len-cmd_o do buffer[i-1] := ord(com_line[cmd_o+i]);
buf_length := cmd_len - cmd_o;
end
else buf_length := 0;
if cmd_o<cmd_len then cmd_len := cmd_o-1;
got_file_name:=(cmd_i<=cmd_o) and (cmd_len>0);
if got_file_name then @<Parse names of files@>
else @<Input names of files@>;
open(dvi_file,dvi_fname,@=readonly@>,
@=user_action:=@>dvi_open,@=error:=continue@>);
if status(dvi_file)<>0 then begin
write_ln('Cannot open dvi file!');
goto 9999;
end;
open(bit_file,bit_fname,@=new,32767@>,@=error:=continue@>);
if status(bit_file)<>0 then begin
write_ln('Cannot open bit file or printer output');
goto 9999;
end;
@ If the name of the |dvi_file| appears in the command line, we parse it.
@<Parse names of files@>=
begin cmd_e:=cmd_i+1;
while (cmd_e<=cmd_len) and (com_line[cmd_e]<>' ') do incr(cmd_e);
decr(cmd_e);
dvi_fname:=substr(com_line,cmd_i,cmd_e-cmd_i+1)+'.DVI';
cmd_i:=cmd_e+1;
while (cmd_i<=cmd_len) and (com_line[cmd_i]=' ') do incr(cmd_i);
if cmd_i<cmd_o then begin
cmd_e:=cmd_i;
while (cmd_e<=cmd_len) and (com_line[cmd_e]<>' ') do incr(cmd_e);
decr(cmd_e);
bit_fname:=substr(com_line,cmd_i,cmd_e-cmd_i+1)+'.VUT';
end
else bit_fname:='SYS$OUTPUT';
end
@ If the name of the |dvi_file| does not appear in the command line, we must
get one from the user.
@<Input names of files@>=
begin
write('DVI file: ');
if eof then goto 9999;
read_ln(dvi_fname);
write('VUT file: ');
if eof then goto 9999;
read_ln(bit_fname);
if bit_fname.VAX_length=0 then bit_fname:='SYS$OUTPUT';
end
@ Here is the library procedure that gets the user's command line.
@<Procedures for ...@>=
[VAX_external] function VAX_lib_get_foreign(
VAX_stdescr cmdlin:[VAX_volatile] packed array [$l1..$u1:integer] of char
:= VAX_immed 0;
VAX_stdescr prompt:[VAX_volatile] packed array [$l2..$u2:integer] of char
:= VAX_immed 0;
var len : [VAX_volatile] sixteen_bits := VAX_immed 0;
var flag : [VAX_volatile] integer := VAX_immed 0)
:integer; extern;
@ Here is how we intervene to find out the length of the |dvi_file|.
@<Procedures for ...@>=
function dvi_open(var fab:VAX_fab_type; var rab:VAX_rab_type):integer;
type XAB_ptr = ^VAX_xab_type;
var user_status:integer;
xab,fhc:XAB_ptr;
begin
user_status:=@= $OPEN@>(fab);
if odd(user_status) then @= $CONNECT@>(rab);
xab:=fab.VAX_fab_xab::XAB_ptr;
fhc:=nil;
while (xab<>nil) and (fhc=nil) do
if xab^.VAX_xab_cod=VAX_xab_fhc then fhc:=xab
else xab:=xab^.VAX_xab_nxt::XAB_ptr;
if fhc<>nil then dvi_blocks:=int(fhc^.VAX_xab_ebk)
else dvi_blocks:=0;
dvi_open:=user_status;
end;
@z